#pragma once
#include <core/sync/lock.h>
#include <list>

template<class SharedResource>
class CSharedResourceManager
{
	typedef std::list<SharedResource*> LargeResourceList;
	qb::base::CSLock		m_lock;
	LargeResourceList		m_caches;
public:
	static CSharedResourceManager& Get()
	{
		static CSharedResourceManager cache_manager;
		return cache_manager;
	}
	CSharedResourceManager(){}
	~CSharedResourceManager(){}
	SharedResource* Alloc()
	{
		SharedResource* cache = 0;
		SCOPED_LOCK(m_lock);
		if (!m_caches.empty())
		{
			cache = m_caches.front();
			m_caches.pop_front();
		}
		else
		{
			cache = new SharedResource();
		}			
		return cache;
	}

	void Free(SharedResource* cache)
	{
		SCOPED_LOCK(m_lock);
		if (cache)
		{
			if (!m_caches.empty())
				delete cache;
			else
				m_caches.push_back(cache);
		}
	}
};

template<class SharedResource>
class CSharedResourcePtr
{
	SharedResource*	m_ptr;
public:
	CSharedResourcePtr() :m_ptr(0)
	{
		m_ptr = CSharedResourceManager<SharedResource>::Get().Alloc();
	}
	~CSharedResourcePtr()
	{
		CSharedResourceManager<SharedResource>::Get().Free(m_ptr);
	}
	SharedResource* Get(){ return m_ptr; }
	SharedResource& operator*(){ return *m_ptr; }
	SharedResource* operator->(){ return m_ptr; }
};